Intro
I will keep my notes of the Go lang here.
Packages
Every Go Program is made up of packages. programs start running in package ‘main’ - the ‘main’ package is unique because it is the entry point to the program, only one source file can use ‘package main’
Go import packages using the import statement with the associated import path for that package. Go searches for that package in the GOPATH env variable.
import (
"fmt",
"math/rand"
)
every source file in the same directory must belong to the same package
thus, every source file must have the same package declaration at the top: go package foo
thus a package is a collection of Go source files in the same directory
to import subpackages, use the following import path:
import "parent_package/sub_package"
by convention the package name is the same as the last element in the import path
Modules
Modules are composed of packages and every module is identified by a Module Path which is declared in a go.mod file
to resolve a package to a specific module, the specific package must be a subdirectory in the module
Exports from Packages Go only exports those identifiers that start with an upper-case letter,
if it doesn’t start with an upper-case, it isn’t accessible outside the file.
Variables
var declares a list of variables and the type goes last
a var statement can be at package or function level
var arg1, arg2, arg3 int
or
var arg1, arg2, arg3 = true, "Hello", 1
a var statement can include initializers, one per variable, and and the type can be left off if initializers are provided
‘:=’ can be used inside of functions with implicit type declarations, this is unavailable outside of functions because every statement begins with a keyword: var, func, etc.
type declarations in Go look like
int
x
total float*int
ref [3]int
array []string slice
type declarations use a left-to-right reading/parsing method
it deviates from the C-style type declarations where the type declaration came before the identifier:
This style becomes increasingly harder to parse as the the type declaration becomes further recursive:
int (*fp)(int (*ff)(int x, int y), int b)
a function pointer that takes a another pointer to function as an argument that takes 2 ints, x & y, and another int argument
expressions involving pointers and slices looks like in Go:
= array[0]
x = * value
function declarations look like the following:
func
if you have multiple consecutive arguements that all share the same type then you only need to specify the type on the last argument
func (arg1, arg2, arg3 int, arg4 string, arg5, arg6 float)
Arrays
arrays are like your standard C array: a contiguous block of memory that holds a definitive number of elements of a specific type. The array is a fixed width type
/*
+----+----+----+
| 1 | 2 | 3 |
+----+----+----+
*/
Arrays Abstracted: Slice Types
slices are a view into contiguous segment of an underlying array. A slice is always associated with it’s underlying array and make share array storage with other slices of the same array. a slice type has a length and a capacity. The capacity is the total number of possible elements in an array but the length of the slice is the total length of a segment of the unerlying array.
you can construct new slices using the builtin make
make([]T, length, capacity)
Structs
structs are simply a collection of different variables of varying types collected into one type. e.g.
type ticket struct {
string `json:"name"`
TaskName string `json:"username"`
AssignedTo string `json:"description"`
Description `json:"state"`
TicketState State }
here we have a struct, which is collection of variables that associated to each other because they represent aspects of a ‘ticket’ in a project management context, three of the variables are represented as strings and the fourth one is of type ‘State’. State here is another syntactical type structure called an Enum
Enums
As far as I can tell enums in Go don’t feel very satisfying as say an enum in C++ or Python. Here’s what an enum looks like in Go
type State int
const (
= iota
Waiting State
InProgress
Complete)
func (s State) String() string {
switch s {
case Waiting:
return "waiting"
case InProgress:
return "In Progress"
case Complete:
return "Complete"
default:
return "Unknown State"
}
}
we can attach specific functions to instances of certain types using the follwing syntax
func (<varname> <type>) <func_name>() <return_type>
References
https://go.dev/blog/declaration-syntax